﻿using System.Windows;

namespace Gmantis.Controls.DataGrid
{
    public class DataGridViewport
    {
        // Methods
        internal DataGridViewport(DataGridView view)
        {
            this.View = view;
            this.VisibleColumns = new DataGridVisibleItems<DataGridColumn>(column => column.DisplayIndex, column => column.IsFrozen);
            this.VisibleRows = new DataGridVisibleItems<DataGridRow>(row => row.Index, row => row.IsFrozen);
        }

        internal bool IsMaster(DataGridCell cell)
        {
            DataGridCell topLeftCell = cell.Presenter.MergedRange.TopLeftCell;
            if ((topLeftCell.Row != cell.Row) && (cell.Row != this.Rows[0]))
            {
                return false;
            }
            if ((topLeftCell.Column != cell.Column) && (cell.Column != this.Columns[0]))
            {
                return false;
            }
            return true;
        }

        internal DataGridCellsRange Range(DataGridCell cell)
        {
            if (cell.Presenter == null)
            {
                return new DataGridCellsRange(cell);
            }
            return cell.Presenter.MergedRange;
        }

        public void ScrollToHorizontalOffset(double horizontalOffset)
        {
            this.View.ScrollManager.ScrollHorizontally(horizontalOffset);
        }

        public void ScrollToVerticalOffset(double verticalOffset)
        {
            this.View.ScrollManager.ScrollVertically(verticalOffset);
        }

        internal bool VisibleRange(DataGridCellsRange range, out int left, out int top, out int right, out int bottom)
        {
            left = this.VisibleColumns.GetIndexFromItem(range.TopLeftCell.Column);
            top = this.VisibleRows.GetIndexFromItem(range.TopLeftCell.Row);
            right = this.VisibleColumns.GetIndexFromItem(range.BottomRightCell.Column);
            bottom = this.VisibleRows.GetIndexFromItem(range.BottomRightCell.Row);
            if (left < 0)
            {
                left = ~left;
                if (left == this.VisibleColumns.Items.Length)
                {
                    return false;
                }
            }
            if (top < 0)
            {
                top = ~top;
                if (left == this.VisibleRows.Items.Length)
                {
                    return false;
                }
            }
            if (right < 0)
            {
                right = ~right;
                if (right == 0)
                {
                    return false;
                }
                right--;
            }
            if (bottom < 0)
            {
                bottom = ~bottom;
                if (bottom == 0)
                {
                    return false;
                }
                bottom--;
            }
            if (right < left)
            {
                return false;
            }
            if (bottom < top)
            {
                return false;
            }
            return true;
        }

        // Properties
        public DataGridCellsRange CellsRange
        {
            get
            {
                if (((this.FirstVisibleColumn < 0) || (this.LastVisibleColumn < 0)) || ((this.FirstVisibleRow < 0) || (this.LastVisibleRow < 0)))
                {
                    return null;
                }
                DataGridColumn column = this.View.Model.Columns.OrderedColumns[this.FirstVisibleColumn];
                DataGridColumn column2 = this.View.Model.Columns.OrderedColumns[this.LastVisibleColumn];
                DataGridRow row = this.View.Model.Rows[this.FirstVisibleRow];
                DataGridRow row2 = this.View.Model.Rows[this.LastVisibleRow];
                return new DataGridCellsRange(this.View.DataGrid[row, column], this.View.DataGrid[row2, column2]);
            }
        }

        public DataGridColumn[] Columns
        {
            get
            {
                return this.VisibleColumns.Items;
            }
        }

        public Size ExtentSize
        {
            get
            {
                return new Size(this.View.ScrollManager.ExtentWidth, this.View.ScrollManager.ExtentHeight);
            }
        }

        public int FirstVisibleColumn
        {
            get
            {
                return this.VisibleColumns.FirstVisibleItem;
            }
        }

        public int FirstVisibleRow
        {
            get
            {
                return this.VisibleRows.FirstVisibleItem;
            }
        }

        public double HorizontalOffset
        {
            get
            {
                return this.View.ScrollManager.HorizontalOffset;
            }
        }

        public int LastVisibleColumn
        {
            get
            {
                return this.VisibleColumns.LastVisibleItem;
            }
        }

        public int LastVisibleRow
        {
            get
            {
                return this.VisibleRows.LastVisibleItem;
            }
        }

        public DataGridRow[] Rows
        {
            get
            {
                return this.VisibleRows.Items;
            }
        }

        public Size Size
        {
            get
            {
                return this.View.ScrollManager.Viewport;
            }
        }

        public double VerticalOffset
        {
            get
            {
                return this.View.ScrollManager.VerticalOffset;
            }
        }

        internal DataGridView View { get; private set; }

        internal DataGridVisibleItems<DataGridColumn> VisibleColumns { get; private set; }

        internal DataGridVisibleItems<DataGridRow> VisibleRows { get; private set; }
    }
}
